import argparse
import base64
import logging
import os
from typing import List, Optional

import requests


class HumeAIProvider:
    """Provider for HumeAI text-to-speech synthesis."""

    def __init__(self, api_key: Optional[str] = None):
        """Initialize the HumeAI TTS provider.

        Args:
            api_key: The HumeAI API key. If not provided, will try to get from environment.
        """
        self.api_key = api_key or os.environ.get("HUME_API_KEY")
        if not self.api_key:
            raise ValueError(
                "HumeAI API key not provided and not found in environment variables"
            )

        self.base_url = "https://api.hume.ai/v0/tts"

    def synthesize_text(
        self,
        text: str,
        output_file: str,
        voice_description: Optional[str] = None,
        audio_format: str = "mp3",
    ) -> str:
        """Synthesize a single text utterance to audio file.

        Args:
            text: The text to synthesize
            output_file: Path to save the audio file
            voice_description: Optional description of the voice to use
            audio_format: Audio format (mp3, wav, etc.)

        Returns:
            Path to the generated audio file
        """
        headers = {"X-Hume-Api-Key": self.api_key, "Content-Type": "application/json"}

        utterance = {"text": text}
        if voice_description:
            utterance["description"] = voice_description

        payload = {
            "utterances": [utterance],
            "format": {"type": audio_format},
            "num_generations": 1,
        }

        response = requests.post(self.base_url, headers=headers, json=payload)

        if response.status_code != 200:
            logging.error(f"Error from HumeAI API: {response.text}")
            raise Exception(
                f"HumeAI API error: {response.status_code}, {response.text}"
            )

        result = response.json()
        audio_base64 = result["generations"][0]["audio"]

        # Decode and save audio
        audio_data = base64.b64decode(audio_base64)
        with open(output_file, "wb") as f:
            f.write(audio_data)

        return output_file

    def synthesize_from_file(
        self,
        input_file: str,
        output_dir: str,
        voice_description: Optional[str] = None,
        audio_format: str = "mp3",
    ) -> List[str]:
        """Synthesize audio for each line in a text file.

        Args:
            input_file: Path to the input text file (one utterance per line)
            output_dir: Directory to save the generated audio files
            voice_description: Optional description for the voice
            audio_format: Audio format (mp3, wav, etc.)

        Returns:
            List of paths to the generated audio files
        """
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        output_files = []

        with open(input_file, "r", encoding="utf-8") as f:
            lines = [line.strip() for line in f.readlines() if line.strip()]

        for i, line in enumerate(lines):
            output_file = os.path.join(output_dir, f"audio_{i + 1}.{audio_format}")
            self.synthesize_text(line, output_file, voice_description, audio_format)
            output_files.append(output_file)

        return output_files


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="HumeAI TTS synthesizer")
    parser.add_argument(
        "input_file", help="Path to input text file (one utterance per line)"
    )
    parser.add_argument(
        "output_dir", help="Directory to save the generated audio files"
    )
    parser.add_argument(
        "--voice", help="Optional description of the voice to use", default=None
    )
    parser.add_argument("--format", help="Audio format (mp3, wav, etc.)", default="mp3")
    parser.add_argument(
        "--api_key", help="HumeAI API key (if not set in environment)", default=None
    )

    args = parser.parse_args()

    provider = HumeAIProvider(api_key=args.api_key)
    output_files = provider.synthesize_from_file(
        input_file=args.input_file,
        output_dir=args.output_dir,
        voice_description=args.voice,
        audio_format=args.format,
    )

    print(f"Generated {len(output_files)} audio files in {args.output_dir}")
    for file in output_files:
        print(f"- {file}")